package com.zzw.thread.safe;

import sun.misc.Unsafe;

import java.lang.reflect.Field;

/**
 * @author zzw
 * @see
 * @since 2018/3/30
 */
public class CASCounter implements Counter{

    private volatile long counter = 0;
    private Unsafe unsafe;
    private long offset = 0;

    public CASCounter() throws NoSuchFieldException, IllegalAccessException {
        setUnsafe();
        offset = unsafe.objectFieldOffset(CASCounter.class.getDeclaredField("counter"));
    }

    @Override
    public void increment() {
        long before = counter;
        while (!unsafe.compareAndSwapLong(this,offset,before,before + 1)){
            before = counter;
        }
    }

    @Override
    public long getCounter() {
        return counter;
    }

    public void setUnsafe() throws NoSuchFieldException, IllegalAccessException {
        Field f = Unsafe.class.getDeclaredField("theUnsafe");
        f.setAccessible(true);
        unsafe = (Unsafe) f.get(null);
    }
}
